from querier.esquerier import ElasticSearchQuerier

MINIMUM_SHOULD_MATCH = '5<85% 10<9'


class JDShopGoodsQuerier(ElasticSearchQuerier):
    def __init__(self, es, index, doc_type):
        super(JDShopGoodsQuerier, self).__init__(None, None, None)
        self.es = es
        self.index = index
        self.doc_type = doc_type

    def _build_query(self, args):
        shop_id = args.get('shop_id', None)
        if shop_id is None:
            raise ValueError('"shop_id" is needed.')

        filters = args.get('filters', {})
        from_ = args.get('from', 0)
        size_ = args.get('size', 4)

        filter_clause = [{"term": {"shop_id": shop_id}}]
        if filters:
            filter_clause += add_filter_range_clause(filters, 'goods_start_date')

        must_clause = list()

        must_clause.append(
            {
                "match": {
                    "shop_id":
                        {"query": shop_id,
                         "minimum_should_match": MINIMUM_SHOULD_MATCH
                         }
                }
            }
        )

        query = {"query": {
            "bool": {
                "filter": filter_clause,
                "must": must_clause
            }
        }, 'from': from_, 'size': size_, 'sort': [{'goods_start_date': 'desc'}]}
        return query, {}, {}

    def _build_result(self, es_result, param):
        total = es_result['hits']['total']
        goods = []
        for hit in es_result['hits']['hits']:
            goods.append(extract_result(hit))
        return {
            'total': total,
            'goods': goods
        }


def add_filter_range_clause(filters, key):
    clause = []
    if key in filters:
        if filters[key]:
            clause = []
            fk = filters[key]
            if not isinstance(fk, list) or len(fk) < 1:
                pass
            else:
                min_fk = fk[0]
                if len(fk) >= 2:
                    max_fk = fk[1]
                else:
                    max_fk = None
                if min_fk is not None and min_fk != 'null':
                    clause.append({'range': {key: {"gte": min_fk}}})
                if max_fk is not None and max_fk != 'null':
                    clause.append({'range': {key: {"lte": max_fk}}})
    return clause


def extract_result(hit):
    source_ = hit['_source']
    goods_id = source_['goods_id']
    img_url = source_['img_url']
    goods_url = source_['goods_url']
    goods_start_date = source_['goods_start_date']
    goods_end_date = source_['goods_end_date']
    commission_ratio_pc = source_['commission_ratio_pc']
    commission_ratio_wl = source_['commission_ratio_wl']
    commission_pc = source_['commission_pc']
    commission_wl = source_['commission_wl']
    goods_name = source_['goods_name']
    company_name = source_.get('company_name', '')
    # company_promotion_url = source_['company_promotion_url']
    thirty_order_count = source_['thirty_order_count']
    intros = source_.get('intros', '')
    comments = source_.get('comments', '')
    price = source_['price']
    brand = source_.get('brand', '')
    shop_id = source_['shop_id']
    thirty_commission_expense = source_['thirty_commission_expense']
    unit_price_pc = source_['unit_price_pc']
    unit_price_wl = source_['unit_price_wl']
    keywords = source_['keywords']
    created_at = source_['created_at']
    updated_at = source_['updated_at']

    return {
        'goods_id': goods_id,
        'img_url': img_url,
        'goods_url': goods_url,
        'goods_start_date': goods_start_date,
        'goods_end_date': goods_end_date,
        'commission_ratio_pc': commission_ratio_pc,
        'commission_ratio_wl': commission_ratio_wl,
        'commission_pc': commission_pc,
        'commission_wl': commission_wl,
        'goods_name': goods_name,
        'company_name': company_name,
        'thirty_order_count': thirty_order_count,
        'intros': intros,
        'comments': comments,
        'price': price,
        'brand': brand,
        'shop_id': shop_id,
        'thirty_commission_expense': thirty_commission_expense,
        'unit_price_pc': unit_price_pc,
        'unit_price_wl': unit_price_wl,
        'keywords': keywords,
        'created_at': created_at,
        'updated_at': updated_at
    }
